package top.jnaw.jee.platform.controller.basics.extend;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import java.util.List;
import top.jnaw.jee.platform.Consts;
import top.jnaw.jee.platform.Consts.Result;
import top.jnaw.jee.platform.model.DepartmentType;
import top.jnaw.jee.utils.Models;
import top.jnaw.jee.utils.Strings;

public class TitleDescController extends Controller {

  private static final String kFieldTitle = "title";
  private static final String kFieldDescription = "description";

  private static final JSONArray kKeys = new JSONArray();

  static {
    JSONObject department_type = new JSONObject();
    department_type.put("key", "/department/type");
    department_type.put("table", "department_type");
    department_type.put("class", DepartmentType.class);
    kKeys.add(department_type);
  }


  private static JSONObject getKeyObject(String key) {
    JSONObject result = null;

    int size = kKeys.size();
    for (int i = 0; i < size; ++i) {
      JSONObject k = kKeys.getJSONObject(i);
      if (k.containsKey("key") && k.getString("key").equals(key)) {
        result = k;
        break;
      }
    }

    return result;
  }

  private static Class getKeyClass(String key) {
    Class clz = null;

    int size = kKeys.size();
    for (int i = 0; i < size; ++i) {
      JSONObject k = kKeys.getJSONObject(i);

      if (k.getString("key").equals(key)) {
        clz = k.getObject("class", Class.class);
        break;
      }
    }

    return clz;
  }

  /**
   * -> title, ~description~ <p> <- result, data: id
   */
  public void add() {
    final Class modelClz = getKeyClass(getControllerKey());
    JSONObject req = Strings.toJSONObject(this);
    final String title = Strings.getString(req, kFieldTitle, "");
    final String description = Strings.getString(req, kFieldDescription, "");
    Result result = Result.kBadParam;
    Model model = null;

    if (null != modelClz && StrKit.notBlank(title)) {
      try {
        model = (Model) modelClz.newInstance();
        model.set(kFieldTitle, title);
        model.set(kFieldDescription, description);
        result = model.save() ? Result.kSuccess : Result.kModelSaveError;
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJsonId(model, result));
  }

  /**
   * -> id <p> <- result, data: {model}
   **/
  public void delete() {
    final Class modelClz = getKeyClass(getControllerKey());
    JSONObject req = Strings.toJSONObject(this);
    final int id = Strings.getInt(req, "id", Consts.DEFAULT_BAD_ID);
    Result result = Result.kBadParam;
    Model model = null;

    if (null != modelClz) {
      try {
        model = (Model) modelClz.newInstance();
        model = model.findById(id);

        if (null != model) {
          result = model.delete() ? Result.kSuccess : Result.kModelDeleteError;
        } else {
          result = Result.kNull;
        }
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJsonObject(model, result));
  }

  /**
   * -> ~page~, ~size~ <p> <- result, page, size, total, rows, data: [{model}]
   **/
  public void page() {
    final String table = getKeyObject(getControllerKey()).getString("table");
    JSONObject req = Strings.toJSONObject(this);
    final int page = req.containsKey(Consts.JSON_RES_PAGE)
                     ? req.getIntValue(Consts.JSON_RES_PAGE)
                     : Consts.DEFAULT_PAGE;
    final int size = req.containsKey(Consts.JSON_RES_SIZE)
                     ? req.getIntValue(Consts.JSON_RES_SIZE)
                     : Consts.DEFAULT_PAGE_SIZE;
    Result result = Result.kBadParam;
    Page pages = null;

    if (null != table) {
      try {
        pages = Db.paginate(page, size, "SELECT id, title, description",
            "FROM " + table);
        if (null != pages && null != pages.getList()) {
          result = Result.kSuccess;
        } else {
          result = Result.kNull;
        }
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJson(pages, result));
  }

  /**
   * -> _ <p> <- result, data: [{model}]
   **/
  public void list() {
    final String table = getKeyObject(getControllerKey()).getString("table");

    Result result = Result.kBadParam;
    List list = null;

    if (null != table) {
      try {
        list = Db.find("SELECT id, title, description FROM " + table);
        result = (null != list) ? Result.kSuccess : Result.kNull;
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJson(list, false, result));
  }

  /**
   * -> id <p> <- result, data: {model}
   **/
  public void query() {
    final Class modelClz = getKeyClass(getControllerKey());
    JSONObject req = Strings.toJSONObject(this);
    final int id = Strings.getInt(req, "id", Consts.DEFAULT_BAD_ID);
    Result result = Result.kBadParam;
    Model model = null;

    if (null != modelClz) {
      try {
        model = (Model) modelClz.newInstance();
        model = model.findById(id);
        result = null != model ? Result.kSuccess : Result.kNull;
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJsonObject(model, result));
  }

  /**
   * -> id, ~title~, ~description~ <p> <- result, data: {model}
   */
  public void update() {
    final Class modelClz = getKeyClass(getControllerKey());
    JSONObject req = Strings.toJSONObject(this);
    final int id = Strings.getInt(req, "id", Consts.DEFAULT_BAD_ID);
    final String title = Strings.getString(req, kFieldTitle, "");
    final String description = Strings.getString(req, kFieldDescription, "");
    Result result = Result.kBadParam;
    Model model = null;

    if (null != modelClz) {
      try {
        model = (Model) modelClz.newInstance();
        model = model.findById(id);

        if (null != model) {
          if (StrKit.notBlank(title)) {
            model.set(kFieldTitle, title);
          }

          if (StrKit.notBlank(description)) {
            model.set(kFieldDescription, description);
          }

          result = model.update() ? Result.kSuccess : Result.kModelUpdateError;
        } else {
          result = Result.kNull;
        }
      } catch (Exception e) {
        e.printStackTrace();
        result = Result.kException;
      }
    }

    renderJson(Models.toJsonObject(model, result));
  }

}
